﻿Imports StandAuto.Models
Imports StandAuto.Models.ModuleExtentrions
Public Class FormTransacao
    Public Property veiculo As Veiculo
    Public Property compra As Compra
    Public Property venda As Venda
    Public Property cliente As Cliente
    Public Property vendedor As Vendedor
    Public Property fornecedor As Fornecedor
    Public Property isVenda As Boolean

    Private Enum tipoTransacao
        compra
        venda
    End Enum
    'vamos usar um template para selecionar um valor na combobox
    'Esta funçao usa type templates
    'e usa reflection para comparar e selecionar o item
    Private Sub selectIncmb(Of T)(combo As ComboBox, item As T, propertyToCompair As String)
        Dim propInfo As Reflection.PropertyInfo = item.GetType().GetProperty(propertyToCompair)
        For Each itmCmb As T In combo.Items
            If propInfo.GetValue(itmCmb) = propInfo.GetValue(item) Then
                combo.SelectedIndex = combo.Items.IndexOf(itmCmb)
            End If
        Next
    End Sub


    Private Sub FormTransacao_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
        If veiculo IsNot Nothing Then
            'CmbVeiculo.SelectedIndex = CmbVeiculo.Items.IndexOf(itmVeiculo)
            selectIncmb(Of Veiculo)(CmbVeiculo, veiculo, "Id")
            CmbVeiculo.Enabled = False
        End If
        If fornecedor IsNot Nothing Then
            TabControl1.SelectedTab = TabPageCompra
            selectIncmb(Of Fornecedor)(CmbFornecedor, fornecedor, "id")
        End If
        If cliente IsNot Nothing Then
            TabControl1.SelectedTab = TabPageVenda
            selectIncmb(Of Cliente)(CmbCliente, cliente, "id")
        End If
        If vendedor IsNot Nothing Then
            TabControl1.SelectedTab = TabPageVenda
            selectIncmb(Of Vendedor)(CmbVendedor, vendedor, "id")
        End If

        If venda IsNot Nothing Then
            selectIncmb(Of Cliente)(CmbCliente, venda.cliente, "id")
            selectIncmb(Of Vendedor)(CmbVendedor, venda.vendedor, "id")
            TxtbxValorVenda.Text = venda.valor
            TxtIdCompraVenda.Text = venda.id
            DateTimePicker1.Value = venda.data.ConverToDateTime("yyyy-MM-dd")
            NumUpDnQuantidade.Value = venda.quantidade
            TabPageCompra.Enabled = False
        End If
        If compra IsNot Nothing Then
            selectIncmb(Of Fornecedor)(CmbFornecedor, compra.fornecedor, "id")
            TxtbxValorVenda.Text = compra.valor
            TxtIdCompraVenda.Text = compra.id
            DateTimePicker1.Value = compra.data.ConverToDateTime("yyyy-MM-dd")
            NumUpDnQuantidade.Value = compra.quantidade
            TabPageCompra.Enabled = True
            TabPageVenda.Enabled = False
        End If

    End Sub

    Private Sub FormTransacao_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        CmbVeiculo.Items.AddRange(AcessoCamadaDeDados.GetAllViaturas().ToArray())
        CmbCliente.Items.AddRange(AcessoCamadaDeDados.getAllClientes().ToArray())
        CmbFornecedor.Items.AddRange(AcessoCamadaDeDados.GetAllFornecedores().ToArray())
        CmbVendedor.Items.AddRange(AcessoCamadaDeDados.getAllVendedores().ToArray())
        If isVenda Then
            TabControl1.SelectedTab = TabPageVenda
        End If
    End Sub



    Private Sub btnCancelar_Click(sender As Object, e As EventArgs) Handles btnCancelar.Click
        Me.Close()
    End Sub

    Private Sub BtnPesquisaCliente_Click(sender As Object, e As EventArgs) Handles BtnPesquisaCliente.Click
        Pesquisa(Of Cliente)(AcessoCamadaDeDados.getAllClientes(), CmbCliente, "id")
    End Sub
    Private Sub Pesquisa(Of T)(listaAPesquisar As List(Of T), cmbtoSelectResult As ComboBox, campoParaPesquisa As String)
        Dim formpesq As New FormPesquisa()
        formpesq.ListBox1.Items.AddRange(listaAPesquisar.ToArray())
        formpesq.ShowDialog()
        If (formpesq.SelObj IsNot Nothing) Then
            selectIncmb(Of T)(cmbtoSelectResult, formpesq.SelObj, campoParaPesquisa)
        End If
    End Sub

    Private Sub BtnPesquisaVendedor_Click(sender As Object, e As EventArgs) Handles BtnPesquisaVendedor.Click
        Pesquisa(Of Vendedor)(AcessoCamadaDeDados.getAllVendedores(), CmbVendedor, "id")
    End Sub

    Private Sub BtnPesquisaVeiculo_Click(sender As Object, e As EventArgs) Handles BtnPesquisaVeiculo.Click
        Pesquisa(Of Veiculo)(AcessoCamadaDeDados.GetAllViaturas(), CmbVeiculo, "Id")
    End Sub
    Private Sub BtnPesquisaFornecedor_Click(sender As Object, e As EventArgs) Handles BtnPesquisaFornecedor.Click
        Pesquisa(Of Fornecedor)(AcessoCamadaDeDados.GetAllFornecedores, CmbFornecedor, "id")
    End Sub

    Private Sub BtnGuardar_Click(sender As Object, e As EventArgs) Handles BtnGuardar.Click

        Dim validacao As String
        'esta função guarda compra e venda caso o a textbox do valor 
        'esteja preenchido
        'Vamos criar estas flags booleanas para no final da função
        'sabermos o que foi guardado e se correu bem e perguntar se o
        'utilizador pretende fechar a janela da transação.
        Dim guardoucompra As Boolean = False
        Dim guardouvenda As Boolean = False



        'se a textbox do valor de compra estiver preenchido entao é por que é uma compra
        If (Not String.IsNullOrEmpty(TxtBxValCompra.Text)) Then
            validacao = validaCamposParaTransacao(tipoTransacao.compra)
            'se esta tudo pronto para guardar uma compra
            If String.IsNullOrEmpty(validacao) Then
                Dim compraParaGuardar As New Compra() With {
                .data = DateTimePicker1.Value.ToString("yyyy-MM-dd"),
                .fornecedor = New Fornecedor() With {
                .id = getProperty(Of Fornecedor, Integer)(CmbFornecedor.SelectedItem, "id")},
                .fornecedorId = getProperty(Of Fornecedor, Integer)(CmbFornecedor.SelectedItem, "id"),
                .quantidade = NumUpDnQuantidade.Value,
                .valor = TxtBxValCompra.Text,
                .veiculoId = getProperty(Of Veiculo, Integer)(CmbVeiculo.SelectedItem, "Id")
                }
                AcessoCamadaDeDados.guardaCompra(compraParaGuardar)
                guardoucompra = True
            Else
                MessageBox.Show(validacao, "Guardar dados de compra", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
            End If
        End If
        'se a textbox do valor de venda estiver preenchido entao é uma venda
        If (Not String.IsNullOrEmpty(TxtbxValorVenda.Text)) Then
            validacao = validaCamposParaTransacao(tipoTransacao.venda)
            'se esta tudo pronto para guardar uma venda
            If String.IsNullOrEmpty(validacao) Then
                'validar se ha stock soficiente para satisfazer esta venda
                'se é uma venda direta com compra nao validamos
                String.IsNullOrEmpty(TxtBxValCompra.Text)
                If CType(CmbVeiculo.SelectedItem, Veiculo).stock < NumUpDnQuantidade.Value Then
                    If MessageBox.Show("Não há stock suficiente para satisfazer esta venda, stock atual de " & CType(CmbVeiculo.SelectedItem, Veiculo).stock & " viaturas. Deseja continuar o registo da venda ficando com stock negativo?", "Alerta de stock", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) = DialogResult.No Then

                        'nao faz mais nada e sai
                        Exit Sub

                    End If
                End If

                Dim vendaParaGuardar As New Venda() With {
                .data = DateTimePicker1.Value.ToString("yyyy-MM-dd"),
                .cliente = New Cliente() With {.id = getProperty(Of Cliente, Integer)(CmbCliente.SelectedItem, "id")},
                .clienteId = getProperty(Of Cliente, Integer)(CmbCliente.SelectedItem, "id"),
                .quantidade = NumUpDnQuantidade.Value,
                .valor = TxtbxValorVenda.Text,
                .veiculoId = getProperty(Of Veiculo, Integer)(CmbVeiculo.SelectedItem, "Id"),
                .vendedor = New Vendedor() With {.id = getProperty(Of Vendedor, Integer)(CmbVendedor.SelectedItem, "id")},
                .vendedorId = getProperty(Of Vendedor, Integer)(CmbVendedor.SelectedItem, "id")
                }
                AcessoCamadaDeDados.guardaVenda(vendaParaGuardar)
                guardouvenda = True
            Else
                MessageBox.Show(validacao, "Guardar dados de compra", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
            End If
        End If

        'vamos perguntar se pretende fechar a janela
        If guardouvenda Or guardoucompra Then
            Dim pergunta As String = "Transação de "
            If guardoucompra Then
                pergunta &= "compra "
                If guardouvenda Then
                    pergunta &= "e "
                End If
            End If
            If guardouvenda Then
                pergunta &= "venda "
            End If
            pergunta &= "efetuada com sucesso, deseja fechar a janela?"
            If MessageBox.Show(pergunta, "Transação", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = DialogResult.Yes Then
                Me.Close()
            End If

        End If


    End Sub
    Private Function getProperty(Of T, Y)(item As T, propriedade As String) As Y
        Dim ret As Y
        ret = item.GetType().GetProperty(propriedade).GetValue(item)
        Return ret
    End Function
    Private Function validaCamposParaTransacao(tipoTransacao As tipoTransacao) As String
        Dim retorno As String = Nothing
        Select Case tipoTransacao
            Case tipoTransacao.compra
                retorno = validaCamposParaCompra()
            Case tipoTransacao.venda
                retorno = validaCamposParaVenda()
        End Select
        Return retorno
    End Function
    Private Function validadCamposPartilhados() As String
        Dim retorno As String = Nothing
        If (CmbVeiculo.SelectedItem Is Nothing) Then
            retorno = "Tem que selecionar uma viatura."
        End If
        Return retorno
    End Function
    Private Function validaCamposParaCompra() As String
        Dim retorno As String = validadCamposPartilhados()
        If CmbFornecedor.SelectedItem Is Nothing Then
            retorno = IIf(String.IsNullOrEmpty(retorno), "", vbCrLf) & "Tem que selecionar um fornecedor."
        End If
        If Not String.IsNullOrEmpty(retorno) Then
            retorno = "Para concluir a compra:" & vbCrLf & retorno
        End If
        Return retorno
    End Function
    Private Function validaCamposParaVenda() As String
        Dim retorno As String = validadCamposPartilhados()
        If CmbCliente.SelectedItem Is Nothing Then
            retorno = IIf(String.IsNullOrEmpty(retorno), "", vbCrLf) & "Tem que selecionar um cliente."
        End If
        If CmbVendedor.SelectedItem Is Nothing Then
            retorno = IIf(String.IsNullOrEmpty(retorno), "", vbCrLf) & "Tem que selecionar um vendedor."
        End If
        If Not String.IsNullOrEmpty(retorno) Then
            retorno = "Para concluir a compra:" & vbCrLf & retorno
        End If
        Return retorno
    End Function
End Class